#region Using

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;

#endregion

namespace MailDeliveryHelper.BusinessLogic
{
  public class BulkSender
  {
    #region Properties

    private MailMessage _EmailMessage;

    public MailMessage EmailMessage
    {
      get { return _EmailMessage; }
      set { _EmailMessage = value; }
    }

    private List<string> _Recipients;

    public List<string> Recipients
    {
      get { return _Recipients; }
      set { _Recipients = value; }
    }

    private SmtpClient _SmtpSender;

    public SmtpClient SmtpSender
    {
      get { return _SmtpSender; }
      set { _SmtpSender = value; }
    }

    #endregion

    #region Constructor

    public BulkSender(MailMessage emailMessage, List<string> recipients, SmtpClient smtpSender)
    {
      this._EmailMessage = emailMessage;
      this._Recipients = recipients;
      this._SmtpSender = smtpSender;
    }

    public BulkSender()
    {

    }

    #endregion

    #region Methods

    /// <summary>
    /// Sends the email message. Handles delivery failures, and returns a list of e-mail addresses where delivery failed.
    /// </summary>
    /// <returns>Returns a list of e-mail addresses where delivery failed.</returns>
    public List<string> SendEmailMessage()
    {
      List<string> failedRecipients = new List<string>();

      // TODO: Send an e-mail for each X recipeints. Send a chunk of mails at a time.
      // TODO: Start multiple threads to send the e-mails.
      // Clear all recipients
      _EmailMessage.To.Clear();
      _EmailMessage.CC.Clear();
      _EmailMessage.Bcc.Clear();

      for (int i = 0; i < _Recipients.Count; i++)
      {
        // Add the recipient to the Bcc collection
        _EmailMessage.Bcc.Add(_Recipients[i]);
      }

      try
      {
        // Send the MailMessage
        _SmtpSender.Send(_EmailMessage);
      }
      catch (SmtpFailedRecipientsException ex)
      {
        // Delivery failed for the recipient. Add the e-mail address to the failedRecipients List
        failedRecipients.Add(ex.FailedRecipient);
      }
      catch (SmtpFailedRecipientException ex)
      {
        // Delivery failed for the recipient. Add the e-mail address to the failedRecipients List
        failedRecipients.Add(ex.FailedRecipient);
      }
      catch (SmtpException ex)
      {
        throw ex;
      }
      catch (Exception ex)
      {
        throw ex;
      }

      // Return the List of failed recipient e-mail addresses, so the client can maintain its list.
      return failedRecipients;
    }

    #endregion
  }
}
